# -*- coding: utf-8 -*-
'''
    :file: __init__.py
    :author: -Farmer
    :url: https://blog.farmer233.top
    :date: 2021/04/02 16:51:04
'''
import os
import json
from app.ddns.ddns_pack.GetIP import get_ip
from app.ddns.ddns_pack.domain_name_control import get_cloud_ip, updata_ip
from flask import current_app
from app.extensions import scheduler, db
from app.models import DDNSCoreConfig, RRList


class DDNSConfig():

    def __init__(self, accessKeyId: str = None, accessSecret: str  = None, domain_name: str  = None, rr_list: list  = None, path: str  = None) -> None:
        """
        @description: 初始化DDNS，支持缺省配置
        ---------
        @param: accessKeyId：阿里云鉴权密钥
                accessSecret：阿里云鉴权密钥
                domain_name：目标解析域名
                rr_list：子域名列表
        -------
        @Returns: None
        -------
        """
        if path is None:
            path = os.path.join(os.getcwd(), 'config.json')

        if accessKeyId is None or accessSecret is None or domain_name is None or rr_list is None:
            data = self.read_conf(path)
            accessKeyId = data.get('accessKeyId')
            accessSecret = data.get('accessSecret')
            domain_name = data.get('domain_name')
            rr_list = data.get('RR_list')
        else:
            print("update conf")
            data = {
                "accessKeyId": accessKeyId,
                "accessSecret": accessSecret,
                "domain_name": domain_name,
                "RR_list": rr_list
            }
            self.write_conf(path, data)
            self.write_db(data)

        if accessKeyId is None or accessSecret is None or domain_name is None or rr_list is None:
            raise ValueError('Miss key.')

        self.path = path
        self.accessKeyId = accessKeyId
        self.accessSecret = accessSecret
        self.domain_name = domain_name
        self.rr_list = rr_list

    def read_conf(self, path: str) -> dict:
        with open(path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data

    def write_conf(self, path: str, data:dict):
        with open(path, 'w', encoding='utf-8') as f:
            f.write(json.dumps(data))
    
    def write_db(self, data:dict, task_name:str = "ALiDDNSConf") -> bool:
        try:
            conf = DDNSCoreConfig(domain_name = data.get('domain_name'), task_name = task_name)
            conf.set_access(accessKeyId=data.get('accessKeyId'), accessSecret = data.get('accessSecret'))

            for rr in data.get("RR_list"):
                conf.rr_lists.append(RRList(rr_type=rr))
            
            db.session.add(conf)
            db.session.commit()
            return True
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return False



class DDNSCore(DDNSConfig):

    def run(self) -> str:
        if scheduler.get_job(id='ddnsCore'):
            return f'ddnsCore was run...'
        domain_name_ip, domain_name_data = get_cloud_ip(
            self.accessKeyId, self.accessSecret,
            self.domain_name, self.rr_list)
        
        data = self.read_conf(self.path)
        data['domain_name_ip'] = domain_name_ip
        data['domain_name_data'] = domain_name_data
        self.write_conf(self.path, data)
        
        current_app.logger.info(f'ddnsCore init.')
        # func=aps_test, trigger='cron', second='*/5'
        scheduler.add_job(id='ddnsCore', func=run, trigger='interval', seconds=60)
        scheduler.run_job(id='ddnsCore')
        current_app.logger.info(f'ddnsCore running...')
        return 'Start job successful.'


    def _run(self):
        with scheduler.app.app_context():
            base_data = self.read_conf(self.path)
            domain_name_ip = base_data.get('domain_name_ip')
            domain_name_data = base_data.get('domain_name_data')
            try:
                local_ip = get_ip()
                if domain_name_ip != local_ip:
                    for item in domain_name_data:
                        if item['RR'] in self.rr_list:
                            updata_ip(self.accessKeyId, self.accessSecret, item, local_ip)
                    base_data['domain_name_ip'] = local_ip
                    self.write_conf(self.path, base_data)
                    current_app.logger.info(f'domain name ip was update, {domain_name_ip} -> {local_ip}')
            except Exception as e:
                print('定时任务')
                print(type(e))
                current_app.logger.warn(e)


    def stop(self) -> str:
        if scheduler.get_job(id='ddnsCore'):
            scheduler.remove_job(id='ddnsCore')
            current_app.logger.info(f'ddnsCore was stop!')
            return 'ddnsCore was stop!'
        return "ddnsCore not started."


    def state(self) -> str:
        if scheduler.get_job(id='ddnsCore'):
            return f'ddnsCore running...'
        return 'Not core running.'



def run():
    ddns_core = DDNSCore()
    ddns_core._run()

